package com.zecan.blog.service.impl;

import com.zecan.blog.entity.ElasticArticle;
import com.zecan.blog.service.ElasticService;
import com.zecan.blog.vo.elasticsearch.ElasticArticleMsgVo;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName ElasticServiceImpl
 * @Description
 * @date 2022/11/18 23:34
 * @Version 1.0
 */
@Service
public class ElasticServiceImpl implements ElasticService {


    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;


    @Override
    public ElasticArticleMsgVo findArticleByTitleAndDescription(String keyWord, Integer offset, Integer limit) {

        NativeSearchQuery build = new NativeSearchQueryBuilder().
                withQuery(QueryBuilders.multiMatchQuery(keyWord, "article_title", "article_description"))
                // 添加排序
                //.withSorts(SortBuilders.fieldSort("article_create_time").order(SortOrder.DESC))
                 //.withSorts(SortBuilders.fieldSort("articleCreateTime").order(SortOrder.DESC))
                // 添加分页条件
                .withPageable(PageRequest.of(offset, limit))
                .withHighlightFields( // 添加高亮条件
                        new HighlightBuilder.Field("article_title").preTags("<span style='color:red'>").postTags("</span>"),
                        new HighlightBuilder.Field("article_description").preTags("<span style='color:red'>").postTags("</span> "))
                .build();
        SearchHits<ElasticArticle> search = elasticsearchRestTemplate.search(build, ElasticArticle.class);

        // 获取命中的list 集合
        List<SearchHit<ElasticArticle>> searchHits = search.getSearchHits();

        List<ElasticArticle> articleList = new ArrayList<>();

        //数据筛取
        if (searchHits.size() != 0) {
            for (SearchHit<ElasticArticle> searchHit : searchHits) {
                // 获取高亮数据
                Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
                //将高亮的内容填充到content中
                // 如果存在高亮则替换掉原来的 如果不存在则使用原先的 , get的是上面传递回来的实体类中的内容
                searchHit.getContent().setArticleTitle(highlightFields.get("articleTitle") == null ? searchHit.getContent().getArticleTitle() : highlightFields.get("articleTitle").get(0));
                searchHit.getContent().setArticleDescription(highlightFields.get("articleDescription") == null ? searchHit.getContent().getArticleDescription() : highlightFields.get("articleDescription").get(0));
                articleList.add(searchHit.getContent());
            }
        }
        return ElasticArticleMsgVo.builder().articleList(articleList).hitsCount(articleList.size()).build();
    }

    @Override
    public Integer findArticleCountToEs(String keyWord) {
        NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(QueryBuilders.multiMatchQuery(keyWord, "article_title", "article_description").analyzer("ik_max_word"))
                .build();

        SearchHits<ElasticArticle> search = elasticsearchRestTemplate.search(build, ElasticArticle.class);
        return search.getSearchHits().size();
    }
}
